package Day_0218.Object;

/**
 * @author zxc
 * @date 2023/02/18 15:13
 **/
public class Internal_Class {
    public static void main(String[] args) {
        /**
         * 内部类
         * ===》
         * 一.内部类的定义 ：
         * 在Java中，可以将一个类的定义放在另外一个类的定义内部，这就是内部类。
         * 内部类本身就是类的一个属性，与其他属性定义方式一致。
         *
         * 二.内部类可以分为四种：成员内部类、局部内部类、匿名内部类和静态内部类。
         * 1.静态内部类
         * （1）定义在类内部的静态类，就是静态内部类。
         * （2）静态内部类可以访问外部类所有的静态变量，而不可访问外部类的非静态变量；
         *  静态内部类的创建方式， new 外部类.静态内部类() ，如下：
         *  Outer.StaticInner inner = new Outer.StaticInner();
         *  inner.visit();
         *
         * 2.成员内部类
         * （1）定义在类内部，成员位置上的非静态类，就是成员内部类。
         * （2）成员内部类可以访问外部类所有的变量和方法，包括静态和非静态，私有和公有。
         *  成员内部类依赖于外部类的实例，它的创建方式 外部类实例.new 内部类() ，如下：
         *  Outer outer = new Outer();
         *  Outer.Inner inner = outer.new Inner();
         *  inner.visit();
         *
         * 3.局部内部类
         * （1）定义在方法中的内部类，就是局部内部类。
         * （2）定义在实例方法中的局部类，可以访问外部类的所有变量和方法，
         *  定义在静态方法中的局部类只能访问外部类的静态变量和方法。
         *  局部内部类的创建方式，在对应方法内， new 内部类();
         *
         * 4.匿名内部类
         * 1）匿名内部类，就是没有名字的内部类，日常开发中使用的比较多。
         * 2)特点：
         * （1）匿名内部类必须继承一个抽象类或者实现一个接口。
         * （2）匿名内部类不能定义任何静态成员和静态方法。
         * （3）当所在的方法的形参需要被匿名内部类使用时，必须声明为 final。
         * （4）匿名内部类不能是抽象的，它必须要实现继承的类或者实现的接口的所有抽象方法。
         *
         * 三，内部类的优点
         * 1.一个内部类对象，可以访问创建它的外部类对象的内容，包括私有数据！
         * 2.内部类不为同一包的其他类所见，具有很好的封装性；
         * 3.内部类有效实现了“多重继承”，优化 java 单继承的缺陷。
         * ===》即，可以使用外部类的成员对象和成员方法;
         * 4.匿名内部类可以很方便的定义回调。
         *
         * 四，内部类的应用场景
         * 1.一些多算法场合
         * 2.解决一些非面向对象的语句块。
         * 3.适当使用内部类，使得代码更加灵活和富有扩展性。
         * 4.当某个类除了它的外部类，不再被其他的类使用时。
         *
         * 五，局部内部类和匿名内部类访问局部变量的时候，为什么变量必须要加上final？
         * （1）局部内部类和匿名内部类都是定义在外部类的某个方法内部的;
         * （2）是因为生命周期不一致，方法中的局部变量直接存储在栈中，当方法执行结束后，非final的局部变量就被销毁。
         *  而局部内部类对局部变量的引用依然存在，如果局部内部类要调用局部变量时，就会出错。
         *  加了final，可以确保局部内部类使用的变量与外层的局部变量区分开，解决了这个问题
         *
         */
        Internal_Class internal_class = new Internal_Class();
        internal_class.test(2);
    }
    // 1.静态内部类
//    private static int radius = 1;
//    static class StaticInner {
//        public void visit() {
//            System.out.println("visit outer static variable:" + radius);
//        }
//    }

    // 2.成员内部类
//    private static int radius = 1;
//    private int count =2;
//    class Inner {
//        public void visit() {
//            System.out.println("visit outer static variable:" + radius);
//            System.out.println("visit outer variable:" + count);
//        }
//    }

    // 3.局部内部类
//    private int out_a = 1;
//    private static int STATIC_b = 2;
//    public void testFunctionClass() {
//        int inner_c = 3;
//        class Inner {
//            private void fun() {
//                System.out.println(out_a);
//                System.out.println(STATIC_b);
//                System.out.println(inner_c);
//            }
//        }
//        Inner inner = new Inner();
//        inner.fun();
//    }

    //4.匿名内部类
    private void test(final int i) {
        new Service() {
            public void method() {
                for (int j = 0; j < i; j++) {
                    System.out.println("匿名内部类" );
                }
            }
        }.method();
    }
}
//匿名内部类必须继承或实现一个已有的接口
interface Service{
    void method();
}
